//
//  GPSTrainingLDPressButton.swift
//  DaFit
//
//  Created by Paul on 2021/12/16.
//  Copyright © 2022 sylar. All rights reserved.
//

import UIKit
import MYModule


open class GPSTrainingLDPressButton: UIButton {
    /// 计时时长
    public var interval: Float = 2.8
    
    /// 进度条颜色
    open var progressColor: UIColor! {
        didSet {
            self.progressLayer.strokeColor = progressColor.cgColor
        }
    }
    
    private var buttonAction: actionState?
    
    private lazy var progressLayer: CAShapeLayer = {
        let layer = CAShapeLayer()
        layer.fillColor = UIColor.clear.cgColor
        layer.strokeColor = UIColor.GPSTraining.theme.cgColor
        layer.lineWidth = 8
        //        layer.lineCap = CAShapeLayerLineCap.round
        return layer
    }()
    
    private lazy var progressBGLayer: CAShapeLayer = {
        let layer = CAShapeLayer()
        layer.fillColor = UIColor.clear.cgColor
        layer.strokeColor = UIColor.assist_D0D0D0.cgColor
        layer.lineWidth = 8
        layer.lineCap = CAShapeLayerLineCap.round
        return layer
    }()
    
    //    @available(iOS 10.0, *)
    private lazy var link: CADisplayLink = {
        let link = CADisplayLink.init(target: self, selector: #selector(linkRun))
        //        link.preferredFramesPerSecond = 60
        link.add(to: RunLoop.current, forMode: RunLoop.Mode.default)
        link.isPaused = true
        return link
    }()
    
    private var tempInterval: Float = 0.0
    private var progress: Float = 0.0
    private var oldProgress: Float = 0.0
    private var isTimeOut: Bool = false
    private var isPressed: Bool = false
    private var isCancel: Bool = false
    private var ringFrame: CGRect = .zero
    
    
    deinit {
        print("deinit LZPressButton")
        self.link.invalidate()
    }
    
    public override init(frame: CGRect) {
        super.init(frame: frame)
        
        self.backgroundColor = UIColor.clear
        let longPress = UILongPressGestureRecognizer.init(target: self, action: #selector(longPressGesture))
        self.addGestureRecognizer(longPress)
        
        let tap = UITapGestureRecognizer.init(target: self, action: #selector(tapGesture))
        self.addGestureRecognizer(tap)
    }
    
    public required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        let longPress = UILongPressGestureRecognizer.init(target: self, action: #selector(longPressGesture))
        self.addGestureRecognizer(longPress)
        
        let tap = UITapGestureRecognizer.init(target: self, action: #selector(tapGesture))
        self.addGestureRecognizer(tap)
        //        fatalError("init(coder:) has not been implemented")
    }
    
    open func actionWithClosure(_ closure: @escaping actionState) {
        
        self.buttonAction = closure
    }
    
    @objc private func tapGesture() {
        
        if let closure = self.buttonAction {
            closure(.Click)
        }
    }
    
    @objc private func longPressGesture(_ gesture: UILongPressGestureRecognizer) {
        
        switch gesture.state {
        case .began:
            
            self.layer.borderWidth = 0
            self.link.isPaused = false
            self.isPressed = true
            self.layer.addSublayer(self.progressBGLayer)
            self.layer.addSublayer(self.progressLayer)
            if let closure = self.buttonAction {
                closure(.Begin)
            }
        case .changed:
            let point = gesture.location(in: self)
            if self.ringFrame.contains(point) {
                self.isCancel = false
                if let closure = self.buttonAction {
                    closure(.Moving)
                }
            } else {
                self.isCancel = true
                if let closure = self.buttonAction {
                    closure(.WillCancel)
                }
            }
        case .ended:
            log.debug("longPressGesture end")
            self.stop()
            if self.isCancel {
                if let closure = self.buttonAction {
                    closure(.DidCancel)
                }
            }
            self.isTimeOut = false
        default:
            self.stop()
            self.isCancel = true
            if let closure = self.buttonAction {
                closure(.DidCancel)
            }
        }
        
        self.setNeedsDisplay()
    }
    
    @objc private func linkRun() {
        tempInterval += 1/60.0
        progress = tempInterval/interval
        self.setNeedsDisplay()
    }
    
    open func stop() {
        
        isPressed = false
        tempInterval = 0.0
        progress = 0.0
        oldProgress = 0.0
        
        self.layer.borderWidth = 1
        self.progressLayer.strokeEnd = 0
        self.progressLayer.removeFromSuperlayer()
        self.progressBGLayer.removeFromSuperlayer()
        self.link.isPaused = true
        self.setNeedsDisplay()
        
    }
    
    open override func draw(_ rect: CGRect) {
        
        let width = self.bounds.width
        let height = self.bounds.height
        var mainWidth = width
        var mainFrame = CGRect(x: 0, y: 0, width: mainWidth , height: mainWidth)
        
        if self.isPressed {
            let progressPath = UIBezierPath()
            progressPath.move(to: CGPoint(x: width / 2, y: 0))
            progressPath.addLine(to: CGPoint(x: width - height / 2, y: 0))
            progressPath.addArc(withCenter: CGPoint(x: width - height / 2, y: height / 2), radius: height / 2, startAngle: -CGFloat.pi / 2, endAngle: CGFloat.pi / 2, clockwise: true)
            progressPath.addLine(to: CGPoint(x: height / 2, y: height))
            progressPath.addArc(withCenter: CGPoint(x: height / 2, y: height / 2), radius: height / 2, startAngle: CGFloat.pi / 2, endAngle: CGFloat.pi / 2 * 3, clockwise: true)
            progressPath.close()
            
            self.progressLayer.path = progressPath.cgPath
            self.progressBGLayer.path = progressPath.cgPath
            if self.progress >= 1 {
                self.progress = 1
            }
//            log.debug("self.progress = \(self.progress)")
            
            self.progressLayer.strokeEnd = CGFloat(self.progress)
            if self.progress == 1 && self.progress != self.oldProgress{
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.2, execute: { [weak self] in
                    self?.stop()
                    self?.isTimeOut = true
                    if let closure = self?.buttonAction {
                        closure(.End)
                    }
                })
            }
            oldProgress = progress
        }
    }
}

